﻿using System;
using System.IO;

namespace SecureConnection.Utils
{
    public class ByteArrayWriter : IDisposable
    {
        private MemoryStream stream;
        private System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf;

        public int Length { get { return (int)stream.Length; } }
        public int Offset { get { return (int)stream.Position; } }
        public ByteArrayWriter()
        {
            Initialize();
        }
        public ByteArrayWriter(byte[] data)
        {
            WriteBytes(data);

            Initialize();
        }
        public ByteArrayWriter(byte[] data, int offset, int size)
        {
            WriteBytes(data, offset, size);

            Initialize();
        }

        ~ByteArrayWriter()
        {
            Dispose();
        }

        private void Initialize()
        {
            stream = new MemoryStream();
            bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        }

        public void WriteByte(byte b)
        {
            stream.WriteByte(b);
        }

        public void WriteBytes(byte[] b)
        {
            WriteBytes(b, 0, b.Length);
        }
        public void WriteBytes(byte[] b, int offset, int size)
        {
            stream.Write(b, offset, size);
        }

        public void WriteShort(short s)
        {
            WriteBytes(BitConverter.GetBytes(s));
        }

        public void WriteInt(int i)
        {
            WriteBytes(BitConverter.GetBytes(i));
        }

        public void WriteLong(long l)
        {
            WriteBytes(BitConverter.GetBytes(l));
        }

        public void WriteFloat(float f)
        {
            WriteBytes(BitConverter.GetBytes(f));
        }

        public void WriteDouble(double d)
        {
            WriteBytes(BitConverter.GetBytes(d));
        }

        public void WriteUShort(ushort s)
        {
            WriteBytes(BitConverter.GetBytes(s));
        }

        public void WriteUInt(uint i)
        {
            WriteBytes(BitConverter.GetBytes(i));
        }

        public void WriteULong(ulong l)
        {
            WriteBytes(BitConverter.GetBytes(l));
        }

        public void WriteObject(object o)
        {
            MemoryStream m = new MemoryStream();
            bf.Serialize(m, o);
            WriteInt((int)m.Length);
            WriteBytes(m.ToArray());
            m.Close();
            m.Dispose();
        }

        public void WriteString(string s)
        {
            WriteUInt((uint)s.Length);
            WriteBytes(System.Text.Encoding.ASCII.GetBytes(s));          
        }

        public byte[] ToByteArray()
        {
            return stream.ToArray();
        }

        public void Reset()
        {
            Dispose();

            stream = new MemoryStream();
        }

        public void Dispose()
        {
            if (stream != null)
            {
                stream.Close();
                stream.Dispose();
            }
            stream = null;
        }
    }
}
